41. explicit interface & runtime polymorphism for Template programming

C++ 템플릿은 초기에 사용자가 타입에 관계없는 컨테이너(container)를 만들어 사용할 때,
타입 안정성을 부여하기 위해 만들어 졌다.

하지만, 이후 일반화 프로그래밍(generic programming; 조작할 객체의 타입과 상관없이 코드를 작성)부터
템플릿 메커니즘의 튜링 완전성(Turing-complete)을 이용한 템플릿 메타 프로그래밍 영역등 다양하게
사용된다.

1. 템플릿 컨테이너(container)
2. 일반화 프로그래밍(Generic Programming)
객체의 타입과 무관하게 코드를 작성하는 방법
3. 템플릿 메타 프로그래밍(Template Meta Programming)
컴파일러 내부에서 실행되고, 컴파일 과정이 끝날 때 실행을 멈추는 프로그래밍
객체 지향 언어는 명시적 인터페이스(explicit interface)와 런타임 다형성(runtime polymorphism)을
축으로 동작한다.
class Widget{
public:
Widget();
virtual ~Widget(); // -
virtual std::size_t size() const;
virtual void normalize();
void swap(Widget& other);
// ...
};
void doProcessing(Widget& w){
if(w.size()>10 && w!=someNastyWidget){
Widget temp(w); //
temp.normalize();
temp.swap(w);
}
}
소스 코드에서 확인 가능한 인터페이스를 명시적 인터페이스(explicit interface)라고 하며,
가상 함수에 대한 호출을 런타임 다형성(runtime polymorphism)이라고 한다.

템플릿과 일반화 프로그래밍에서는 명시적 인터페이스-런타임 다형성 보다는
암시적 인터페이스(implicit interface)와 컴파일 타임 다형성(compile time polymorphism)을
축으로 한다.
template <typename T>
void doProcessing(T& w){
if(w.size()>10 && w!=someNastyWidget){
T temp(w); //
temp.normalize();
temp.swap(w);
}
}
템플릿으로 선언된 함수에서 T로 선언된 변수 w가 인터페이스를 결정한다.
위에서 w의 타입 T는 size, normalize, swap 멤버 함수를 지원해야 하며,
복사 생성자, 부등 비교 연산자를 지원해야 한다.

컴파일 타임에 템플릿 인스턴스화를 한다.
인스턴스화는 템플릿 매개변수에 따라 달라지기 때문에 이를 컴파일 타임 다형성이라고 한다.

명시적 인터페이스는 대게 함수 시그너처(함수 이름, 매개변수 타입, 반환 타입 등)로 구성된다.
암시적 인터페이스는 유효 표현식(expression)으로 구성된다.
클래스와 템플릿 모두 인터페이스와 다형성을 제공한다.
클래스:
인터페이스 명시적-함수의 시그너처로 구성됨
다형성 프로그램 실행 중 가상함수 이용

템플릿:
인터페이스 암시적-유효 표현식으로 구성
다형성 컴파일 중 템플릿 인스턴스화와 함수 오버로딩으로 모호성 해결